<?php
include_once ("CacheLock.class.php");   //lock操作类


class action extends mysql {
	var $available_throw_num;
	var $user_data_table;
	var $bottle_table;
	var $bottle_pool_table;
	var $message_table;
	var $user_bottle_table;
	var $user_info_table;
	var $fbid_userid_table;
	
	var $default_throw_times;
	var $default_pick_times;
	var $default_credits_add;
	
	var $male_head_array;
	var $female_head_array;
	
	/*构造函数*/
	function __construct($db_host, $db_user, $db_pwd, $db_database, $conn, $coding, $db_tag) {
		parent::__construct($db_host, $db_user, $db_pwd, $db_database, $conn, $coding, $db_tag);
		
		$this->available_throw_num 	= "available_throw_times";
		$this->user_data_table 		= "user_data";
		$this->bottle_table 		= "bottle";
		$this->bottle_pool_table 	= "bottle_pool";
		$this->message_table 		= "message";
		$this->user_bottle_table 	= "user_bottle";
		$this->user_info_table 		= "user_info";
		$this->fbid_userid_table	= "fbid_userid";
		
		$this->default_throw_times	="6";
		$this->default_pick_times	="3";
		$this->default_credits_add	="1";
		
		$this->male_head_array = array();
		$this->female_head_array = array();
		
		$this->male_head_array[0]="../images/heads/male1.jpg";
		$this->male_head_array[1]="../images/heads/male2.jpg";
		$this->male_head_array[2]="../images/heads/male3.jpg";
		$this->male_head_array[3]="../images/heads/male4.jpg";
		$this->male_head_array[4]="../images/heads/male5.jpg";
		
		$this->female_head_array[0]="../images/heads/female1.jpg";
		$this->female_head_array[1]="../images/heads/female2.jpg";
		$this->female_head_array[2]="../images/heads/female3.jpg";
		$this->female_head_array[3]="../images/heads/female4.jpg";
		$this->female_head_array[4]="../images/heads/female5.jpg";
	}
	
	
	// 扔一个新瓶子的操作集成,记得保证message 不是空的
	public function throw_new_bottle($user_id, $message, $type=0){
		//------- 先检查是否有这个用户存在
		if( 0 == $this->check_user_exist($user_id)){
			return 1;
		}
		
		// 先检查是否有可用的瓶子
		$available_throw_times = 0;
		$available_pick_times = 0;
		$credits = 0;
		//$ret = $this->get_user_data($user_id, &$available_throw_time, &$available_pick_times,&$credits);
		$ret = $this->get_user_data($user_id, $available_throw_times, $available_pick_times,$credits);
		if($ret == false){
			return 2;
		}
		if($available_throw_times==null || $available_throw_times == 0){
			return 2;
		}
		
		//-------增加一个瓶子
		$bottle_id = $this->add_bottle($user_id, $user_id, $message,$type);
		if($bottle_id==0){
			return 3;
		}
		
		// ---------池子中增加一个瓶子
		$this->add_bottle_to_pool($bottle_id, $type);
		
		// 增加一个message
		$this->add_message($bottle_id, $user_id, $message);
		
		// -------用户的瓶子关联上
		$this->bind_bottle_to_user($bottle_id, $user_id,0, 1, 1);
		
		// --------用户的可扔瓶子减少，积分增加
		$available_throw_times = $available_throw_times -1;
		if($available_throw_times<0){
			$available_throw_times = 0;
		}
		$credits += $this->default_credits_add;
		$this->update_user_data($user_id, $available_throw_times,$available_pick_times, $credits);
		return 0;
	}
	
	

	/* 
	 * 用户第一次登陆或者使用的时候的初始化操作
	 */
	public function user_login($user_id, $nickname, $sex, $location="" ) {
		// 先检查是否有这个用户存在
		if( 1 == $this->check_user_exist($user_id)){
			// 如果用户已经存在，更新登陆时间，计算可用瓶子数
			$table = $this->user_data_table;
			$time = date('Y-m-d H:i:s');
			
			// 先获取原来的时间
			$ret = $this->select($table, "last_login_time", "user_id=$user_id");
			$row = $this->fetch_array($ret);
			if($row){
				$last_time = $row['last_login_time'];
				
				if(date("Y-m-d",strtotime($time))>date("Y-m-d",strtotime($last_time))){
				    // 如果过了一天了，就更新下可用瓶子数
				    $this->update($table, "available_pick_times=$this->default_pick_times, available_throw_times=$this->default_throw_times", "user_id=$user_id");
				}
				$this->update($table, "last_login_time='$time'", "user_id=$user_id");
				return true;
			}
			else{
				return false;
			}
		}
		
		// if not exist,create it
		$this->create_user($user_id,$nickname, $sex, $location="");
	}

	/* 
	 * 获取用户的一些数据，通过引用传值
	 */
	public function get_user_data($user_id, &$available_throw_times, &$available_pick_times,&$credits){
		$table = $this->user_data_table;
		$ret = $this->select($table, "available_throw_times,available_pick_times, credits", "user_id=$user_id");

		$row = $this->fetch_array($ret);
		if($row){
			$available_throw_times = $row['available_throw_times'];
			$available_pick_times  = $row['available_pick_times'];
			$credits			   = $row['credits'];
			return true;
		}
		return false;
	}
	
	
	/*
	 * 获取用户的所有的瓶子信息，瓶子个数，瓶子内的信息
	 */
	public function get_user_allbottle($user_id){
		$table = $this->user_bottle_table;
		$ret = $this->select($table, "bottle_id, type, is_readed,need_prompt", "user_id=$user_id");
		
		$i = 0;
		$list = array();
		while($row = $this->fetch_array($ret)){
			$list[$i]['bottle_id'] 	= $row['bottle_id'];
			$list[$i]['type'] 		= $row['type'];
			$list[$i]['is_readed'] 	= $row['is_readed'];
			$list[$i]['need_prompt']= $row['need_prompt'];
			$i++;
		}
		return $list;
	}
	
	
	/*
	 * 获取用户的发送的瓶子信息，瓶子个数，瓶子内的信息,
	 * 返回第几个到第几个
	 * SELECT * FROM table LIMIT 5,10；返回第6行到第15行的记录 
	 */
	public function get_user_bottle($user_id, $type, $from , $num){
		$table = $this->user_bottle_table;
		$ret = $this->select($table, "bottle_id, is_readed,need_prompt", "user_id=$user_id and type=$type order by id desc limit $from,$num");
		
		$i = 0;
		$list = array();
		while($row = $this->fetch_array($ret)){
			$list[$i]['bottle_id'] 	= $row['bottle_id'];
			$list[$i]['is_readed'] 	= $row['is_readed'];
			$list[$i]['need_prompt']= $row['need_prompt'];
			$i++;
		}
		return $list;
	}
	
	/*
	 * 获取用户所有的未读瓶子信息
	 */
	public function get_unread_bottle($user_id){
		$table = $this->user_bottle_table;
		$ret = $this->select($table, "bottle_id,is_readed", "user_id=$user_id and is_readed=0");
		$i = 0;
		$list = array();
		while($row = $this->fetch_array($ret)){
			if($row['need_prompt']==0){
				continue;
			}
			$list[$i]['bottle_id'] 	= $row['bottle_id'];
			$i++;
		}
		return $list;
	}
	
		/*
	 * 获取用户所有的未读瓶子个数
	 */
	public function get_unread_bottle_num($user_id){
		$table = $this->user_bottle_table;
		$ret = $this->select($table, "bottle_id", "user_id=$user_id and is_readed=0 and need_prompt=1");
		$total = mysql_num_rows($ret);
		if($total == false){
			return -1;
		}
		return $total;
	}
	
	/*
	 * 从海里捡一个瓶子, return : bottle_id
	 */
	public function pickup_bottle($user_id, $type=-1){
		
		//------- 先检查是否有这个用户存在
		if( 0 == $this->check_user_exist($user_id)){
			return -1;
		}
		$available_throw_times = 0;
		$available_pick_times = 0;
		$credits = 0;
		
		//$this->get_user_data($user_id, &$available_throw_time, &$available_pick_times,&$credits);
		$this->get_user_data($user_id, $available_throw_times, $available_pick_times,$credits);
		
		if($available_pick_times == 0){
			return -2;
		}
		// 从bottle_pool 中随机取得一个瓶子，或者不随机，通过一个函数映射。返回bottle_id
		$id = 0;
		$bottle_id = 0;
		
		// 加锁
		$lock = new CacheLock('pick_bottle');
		
		$lock->lock();
		if($this->getbottle_from_bottlpool($id, $bottle_id, $type)){
			// 减少克pick的次数
			$available_pick_times--;
			$credits += $this->default_credits_add;
			$this->update_user_data($user_id, $available_throw_times,$available_pick_times, $credits);
	
	
			$bottle_senderid = $this->get_senderid($bottle_id);
			if($bottle_senderid == -1 || $bottle_senderid == $user_id){
				// 捞到自己的，返回海藻
				$lock->unlock();
				return -1;
			}
			
			// delete 
			$this->remove_bottle_from_pool($id);
			
			// 把这个bottle加入他的user_bottle里
			$this->bind_bottle_to_user($bottle_id, $user_id, 1, 1,1);
			
			$lock->unlock();
			return $bottle_id;
		}
		$lock->unlock();
		// end lock
		return -1;
	}
	
	/*
	 * 获取一个瓶子内的消息 
	 */
	public function get_bottle_msg($bottle_id,$from, $num){
		// 获取瓶子中的message
		$table = $this->message_table;
		$ret = $this->select($table, "author_id, message, time", "bottle_id=$bottle_id order by id desc limit $from,$num");
		$i = 0;
		$list = array();
		while($row = $this->fetch_array($ret)){
			if(!empty($row)){
				$list[$i]['author_id'] 	= $row['author_id'];
				$list[$i]['message'] 	= $row['message'];
				$list[$i]['time'] 		= $row['time'];
				
				// 用author_id查用户的更加详细的信息
				$list_userdetail = $this->get_user_info($row['author_id']);
				$list[$i]['author_info'] = $list_userdetail;
				
				$i++;
			}
		}
		mysql_free_result($ret);
		return $list;
	}
	
	/*
	 * 获取一个瓶子的信息
	 */
	 public function get_bottle_info($bottle_id){
	 	$ret = $this->select($this->bottle_table, "bottle_id,sender_id, last_response_id, last_message,last_message_time, type, status",
	 	"bottle_id=$bottle_id");
	 	$list = array();
	 	if($row = $this->fetch_array($ret)){
	 		$list['bottle_id']		= $bottle_id;
	 		$list['sender_id'] 		= $row['sender_id'];
	 		$list['last_response_id'] = $row['last_response_id'];
	 		$list['last_message'] 		= $row['last_message'];
	 		$list['last_message_time'] 	= $row['last_message_time'];
	 		$list['type'] 			= $row['type'];
	 		$list['status'] 		= $row['status'];
	 		
	 		$list['sender_info'] 		= $this->get_user_info($row['sender_id']);
	 		$list['last_response_info'] = $this->get_user_info($row['last_response_id']);
	 	}
	 	return $list;
	 }
	

	
	/*
	 * 将一个瓶子不处理，扔回海里
	 */
	 function return_bottle($bottle_id, $type){
		return $this->add_bottle_to_pool($bottle_id, $type);
	 }
	
	/*
	 * 回应一个瓶子，需要保证这个message不是空的
	 */
	public function reply_bottle($user_id, $bottle_id, $message){
		if($message == ""){
			return -1;
		}
		
		// todo 判断瓶子的类型，是否要回应发出者
		$time = date('Y-m-d H:i:s');
		$ret = $this->select($this->bottle_table, "type", "bottle_id=$bottle_id");
		$row = $this->fetch_array($ret);
		if("$row[0]" !=""){
			$type = $row['type'];
			
			$this->update($this->bottle_table, "last_response_id=$user_id, last_message='$message'", "bottle_id=$bottle_id");
			$this->insert($this->message_table, "bottle_id, author_id, message, time","$bottle_id, $user_id, '$message','$time'");
				
			// 如果类型是0, 1，标记其他的使用者未读,以后再改
			if($type==0 || $type ==1){

				// 找出有这个瓶子的其他用户
				$ret = $this->select($this->user_bottle_table, "user_id", "bottle_id=$bottle_id");
				$size = 0;
				$user_list = array();
				while($row = $this->fetch_array($ret)){
					$user_list[$size] = $row['user_id'];
					$size++;
				}
				$i = 0;
				while($i < $size){
					if($user_list[$i] != $user_id){
						$this->update($this->user_bottle_table, "is_readed=0", "user_id=$user_list[$i] and bottle_id=$bottle_id");
					}
					$i++;
				}
			}
		}
		// --------用户积分增加
		$credits = $this->get_credits($user_id);
		$credits += $this->default_credits_add;
		$this->set_credits($user_id, $credits);
		return $type;
	}
	
	/*
	 * 删除一个用户关联的瓶子
	 */
	 function remove_userbottle($user_id, $bottle_id){
	 	$table = $this->user_bottle_table;
		$this->delete($table, "user_id=$user_id and bottle_id=$bottle_id");
	 }
	 
	 /*
	  * 设置是否提醒瓶子未读
	  */
	 function set_prompt_unread($user_id, $bottle_id, $prompt){
	 	$table = $this->user_bottle_table;
	 	$this->update($table, "need_prompt=$prompt", "user_id=$user_id and bottle_id=$bottle_id");
	 }
	 
	 /*
	  * 通过facebook的id得到用户的id， 如果之前没有，则insert一个，然后返回
	  */
	 public function get_userid_fbid($fb_id,$nickname, $sex, $location='secret'){
	 	$ret = $this->select($this->fbid_userid_table, "user_id", "facebook_id=$fb_id");
	 	if($row = $this->fetch_array($ret)){
			$user_id = $row['user_id'];
			return $user_id;
		}
		else{
			$this->insert($this->fbid_userid_table, "facebook_id","$fb_id");
			$user_id = $this->insert_id();
			
			// create user
			$this->create_user($user_id, $nickname, $sex, $location);
			return $user_id;
		}
	 }

	 /*
	  * 获取用户个人的信息, 需要采用原生的sql
	  */
	 function get_user_info($user_id){
		$sql = "select nickname, location, head, sex, receive_setting from ".$this->user_info_table.
			" where user_id=".$user_id;
		$result = mysql_query($sql, $this->conn);
		if(!$result){
			if($this->show_error){
				$this->show_error("select error",$sql);
			}
		}
		
		$list = array();
	 	if($row = mysql_fetch_array($result)){
			$list['nickname'] 	= $row['nickname'];
			$list['location'] 	= $row['location'];
			$list['head'] 		= $row['head'];
			$list['sex'] 		= $row['sex'];
			$list['receive_setting'] = $row['receive_setting'];
			
			if(!$list['nickname'] || trim($list['nickname'])==""){
				$list['nickname'] = "anonymous";
			}
		}
		mysql_free_result($result);
		return $list;
	 }
	 
	 /*
	  * 设置用户信息,return 0，成功， other：error
	  */
	  function set_user_info($user_id, $nickname,$sex,$location, $active_receive){
	  	$ret = $this->check_user_exist($user_id);
	  	if($ret == 0){
	  		return 1;
	  	}
	  	if(!is_numeric($sex)){
	  		return 3;
	  	} 
	  	if(!is_numeric($active_receive)){
	  		return 2;
	  	}
	  	$head_path = $this->get_head_path($sex);
	  	$this->update($this->user_info_table,
				  	 "nickname='$nickname',location='$location',head='$head_path', sex=$sex,receive_setting=$active_receive", 
						"user_id=$user_id");
		
	  	return 0;
	  }
	 
	 function update_lastlogin($user_id){
	 	$ret = $this->check_user_exist($user_id);
	  	if($ret == 0){
	  		return 1;
	  	}
	  	$time = date('Y-m-d H:i:s');
	  	$this->update($this->user_data_table, "last_login_time='$time'","user_id=$user_id");
	  	return 0;
	 }
	 
	 function set_bottle_readed($user_id, $bottle_id){
	 	$ret = $this->check_user_exist($user_id);
	  	if($ret == 0){
	  		return 1;
	  	}
	  	$this->update($this->user_bottle_table, "is_readed=1","user_id=$user_id and bottle_id=$bottle_id");
	  	return 0;
	 }
	 
	 function get_senderid($bottle_id){
	 	$ret = $this->select($this->bottle_table, "sender_id", "bottle_id=$bottle_id");
	 	if($row = $this->fetch_array($ret)){
			$sender_id = $row['sender_id'];
			return $sender_id;
		}
		return -1;
	 }
	 
	 function set_silent($user_id,$bottle_id,$need_prompt){
	 	$ret = $this->update($this->user_bottle_table, "need_prompt=$need_prompt", "user_id=$user_id and bottle_id=$bottle_id");
		return 0;
	 }
	 
	 
	 
	//-private-----------------------------------------------
	
	// 获取user的可以扔的瓶子的个数
	private function get_available_throw_time($user_id){
		// 看user是否有足够的瓶子
		$table = $this->user_data_table;
		$ret = $this->select($table, $this->available_throw_num, "user_id=$user_id");
		$row = $this->fetch_array($ret);
		if("$row[0]" !=""){
			return "$row[0]";
		}
		return null;
	}
	
	// 增加一个瓶子到bottle表
	private function add_bottle($sender_id, $last_response_id, $last_message, $type="0", $status="0"){
		$table = $this->bottle_table;
		$time = date('Y-m-d H:i:s');
		$this->insert($table, "sender_id,last_response_id,last_message,last_message_time, type,status", 
					"$sender_id,$last_response_id,'$last_message','$time', $type,$status") ;
		return $this->insert_id();
	}
	
	
	
	// pool 中增加一个瓶子
	private function add_bottle_to_pool($bottle_id, $type){
		$table = $this->bottle_pool_table;
		$this->insert($table, "bottle_id, type", "$bottle_id, $type") ;
		return $this->insert_id();
	}
	
	// 添加一条信息
	private function add_message($bottle_id, $author_id, $message){
		$table = $this->message_table;
		$time = date('Y-m-d H:i:s');
		$this->insert($table, "bottle_id, author_id, message, time", 
					"$bottle_id, $author_id, '$message','$time'");
		return $this->insert_id();
	}
	
	
	// 将瓶子绑到某个user上
	private function bind_bottle_to_user($bottle_id, $user_id,$type="0", $is_readed="0",$need_prompt="1"){
		$table = $this->user_bottle_table;
		$this->print_error("isread:"+$is_readed);
		$this->insert($table, "user_id, bottle_id, type, is_readed, need_prompt", 
					"$user_id, $bottle_id, $type, $is_readed, $need_prompt");
		return $this->insert_id();
	}
	
	// 获取用户积分
	private function get_credits($user_id){
		$col_name = "credits";
		$table = $this->user_data_table;
		
		$ret = $this->select($table, $col_name, "user_id=$user_id");
		$row = $this->fetch_array($ret);
		if("$row[0]" !=""){
			return "$row[0]";
		}
		return 0;
	}
	
	// 设置用户积分
	private function set_credits($user_id, $credits){
		$table = $this->user_data_table;
		$this->update($table, "credits=$credits", "user_id=$user_id");
	}
	
	
	// 更新user_data
	private function update_user_data($user_id, $available_throw_times,$available_pick_times, $credits){
		$table = $this->user_data_table;
		$this->update($table, "available_throw_times=$available_throw_times," .
				"available_pick_times=$available_pick_times,credits=$credits", "user_id=$user_id");
	}
	
	// 检查用户是否存在，存在返回1.否则返回0
	private function check_user_exist($user_id){
		$table = $this->user_info_table;
		$col_name = "id";
			
		$ret = $this->select($table, $col_name, "user_id=$user_id");
		$row = $this->fetch_array($ret);
		if("$row[0]" !=""){
			return 1;
		}
		return 0;
	}
	
	// 检查瓶子是否存在，存在返回1.否则返回0
	private function check_bottle_exist($bottle_id){
		$table = $this->bottle_table;
		$col_name = "sender_id";
			
		$ret = $this->select($table, $col_name, "bottle_id=$bottle_id");
		
		$row = $this->fetch_array($ret);
		if("$row[0]" !=""){
			return 1;
		}
		return 0;
	}
	
	// create user when user first time use
	private function create_user($user_id, $nickname, $sex, $location='secret' ){
		if($sex==1){
			$head = "../images/heads/male1.jpg";
		}
		else{
			$head = "../images/heads/female1.jpg";
		};
		
		$table = $this->user_info_table;
		$this->insert($table, "user_id, nickname, location, head, sex", 
					"$user_id, '$nickname', '$location','$head', $sex");
					
		$table = $this->user_data_table;
		$available_throw_times = $this->default_throw_times;
		$available_pick_times = $this->default_pick_times;
		$time = date('Y-m-d H:i:s');
		$this->insert($table, "user_id, available_throw_times, available_pick_times,credits, last_login_time", 
					"$user_id, $available_throw_times, $available_pick_times,0, '$time'");
		
	}
	
	// 从bottle_pool中获取一个瓶子,引用传值，返回true，false
	private function getbottle_from_bottlpool(&$id, &$bottle_id, $type=-1){
		$table = $this->bottle_pool_table;
		
		if($type==-1){
			$sql = "select id,bottle_id from $table order by id LIMIT 100";
			$ret = $this->query($sql);
		}
		else{
			$sql = "select id,bottle_id from $table where type=$type order by id LIMIT 100";
			$ret = $this->query($sql);
		}
		
		if(!$ret){
			if($this->show_error){
				$this->show_error("select error",$sql);
			}
		}

		$row_num = $this->db_num_rows($ret);
		if($row_num == 0){
			return false;
		}
		$rand_id = rand(0,$row_num);
		$ret = $this->db_data_seek($ret, $rand_id);
		$row = $this->fetch_row($ret);
		if($row){
			$id = $row[0];
			$bottle_id = $row[1];
			return true;
		}
		return false;
	}
	
	// 从bottle_pool中删除bottle
	private function remove_bottle_from_pool($id){
		$table = $this->bottle_pool_table;
		$this->delete($table, "id=$id");
	}
	
	private function get_head_path($sex){
		$rand_id = rand(0,4);
		if($sex == 1){
			return $this->male_head_array[$rand_id];
		}
		if($sex == 0){
			return $this->female_head_array[$rand_id];
		}
	}
	
} //end class

?>